package com.tengju.data.domain.shared.tree;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.tengju.data.domain.shared.IdObject;
import lombok.Getter;

import javax.validation.constraints.NotNull;
import java.util.*;

@Getter
public class TreeNode<T extends TreeData> {

    private T data;

    @JsonIgnore
    private TreeNode<T> parent;

    @JsonIgnore
    private int depth;

    private Set<TreeNode<T>> children;

    public TreeNode(T data) {
        this.data = data;
    }

    public boolean isVirtualData() {
        return data.isVirtual();
    }

    @JsonIgnore
    public boolean isRoot() {
        return parent == null;
    }

    public IdObject getId() {
        return data.getId();
    }

    public Set<TreeNode<T>> getChildren() {
        return Optional.ofNullable(children)
                .map(Collections::unmodifiableSet)
                .orElse(null);
    }


    void addChildren(@NotNull Set<TreeNode<T>> children) {
        if (this.children == null) {
            this.children = new HashSet<>(children);
        } else {
            this.children.addAll(children);
        }
        this.children.forEach(child -> child.parent = this);
    }

    void updateDepth(int depth) {
        this.depth = depth;
    }

    void fillData(T data) {
        this.data = data;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TreeNode<T> treeNode = (TreeNode<T>) o;
        return Objects.equals(getId(), treeNode.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

    @Override
    public String toString() {
        return getId().toString();
    }

}
